package com.ilia.slitok;

import static com.ilia.slitok.Constants.NUMBER_OF_COORD;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class PolyAlloy {

	public int[] box;
	private List<Alloy> alloys;

	public List<Alloy> getAlloys() {
		return alloys;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof PolyAlloy) {
			return ((PolyAlloy) obj).hashCode() == hashCode();
		}
		return super.equals(obj);
	}

	@Override
	public int hashCode() {
		return Arrays.hashCode(box);
	}

	public static PolyAlloy cloneList(PolyAlloy alloy) {
		PolyAlloy pa = new PolyAlloy();
		ArrayList le = new ArrayList<Alloy>();
		le.addAll(alloy.getAlloys());
		pa.alloys = le;
		pa.box = alloy.box;
		return pa;
	}

	public static PolyAlloy createList(Alloy alloy, int[] box) {
		PolyAlloy pa = new PolyAlloy();
		ArrayList<Alloy> le = new ArrayList<Alloy>();
		le.add(alloy);
		pa.alloys = le;
		pa.box = box;
		return pa;
	}

	public static PolyAlloy createSingle(Alloy alloy, int[] box) {
		PolyAlloy pa = new PolyAlloy();
		ArrayList<Alloy> le = new ArrayList<Alloy>();
		le.add(alloy);
		pa.alloys = le;
		pa.box = box;
		return pa;
	}

	public static int[] createBox(Alloy alloy, int grid) {
		if (grid == 0)
			return createBox(alloy);
		int[] box = new int[2 * NUMBER_OF_COORD];
		for (int i = 0; i < NUMBER_OF_COORD; i++) {
			box[i] = alloy.coord[i] / grid * grid;
			box[i + NUMBER_OF_COORD] = (alloy.coord[i] / grid + 1) * grid;
		}
		return box;
	}

	public static int[] createBox(Alloy alloy) {
		int[] box = new int[NUMBER_OF_COORD];
		for (int i = 0; i < NUMBER_OF_COORD; i++) {
			box[i] = alloy.coord[i];
		}
		return box;
	}

	public String toString() {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < NUMBER_OF_COORD; i++) {
			sb.append("\t" + box[i] + "-" + box[i + NUMBER_OF_COORD]);
		}
		sb.append("\t:");
		sb.append(alloys.toString());
		return sb.toString();
	}

	public void pack() {
		if (alloys.size() < 2)
			return;
		Map<Integer, Alloy> map = new ConcurrentHashMap<Integer, Alloy>();
		for (Alloy alloy : alloys) {
			map.put(Arrays.hashCode(alloy.content_bits), alloy);
		}
		alloys.clear();

		
		int min_sib = map.values().iterator().next().size;
		for (Alloy alloy : map.values()) {
			if (alloys.size() < Traverse.POLY_ALLOY_SIBLINGS) {
				alloys.add(alloy);
				min_sib = (min_sib<alloy.size)?min_sib:alloy.size;
			} else {
				if (min_sib>alloy.size) {
					alloys.add(alloy);
				}
			}
		}

		// alloys.addAll(map.values());
	}

}
